package com.ocm.tourism.web.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Date;
import java.util.Calendar;

import org.springframework.stereotype.Component;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.ocm.tourism.core.domain.FileInfo;
import com.ocm.tourism.core.model.ImageItem;
import com.ocm.tourism.file.MetadataScaleFile;
import com.ocm.tourism.file.ScaleImageService;

@Component
public class FileInfoUtil {

   public static final int DEFAULT_BUFFER_SIZE = 1024 * 4 * 1000;

   private static final String UID =
         new java.rmi.server.UID().toString()
             .replace(':', '_').replace('-', '_');

   static final ScaleImageService scaleImageService ;

   static int counter = 0;

   public MetadataScaleFile createSmall(InputStream inputStream, String contentType, CommonsMultipartFile commonsMultipartFile) throws Exception {
      MetadataScaleFile metadataScaleFile = scaleImageService.scaleSmall(inputStream, contentType);
      metadataScaleFile.setOriginalFile(commonsMultipartFile);
      return metadataScaleFile;
   }
   
   public MetadataScaleFile createMedium(CommonsMultipartFile commonsMultipartFile) throws Exception {
      MetadataScaleFile metadataScaleFile = scaleImageService.scaleMedium(commonsMultipartFile.getInputStream(), commonsMultipartFile.getContentType());
      metadataScaleFile.setOriginalFile(commonsMultipartFile);
      return metadataScaleFile;
   }

   public FileInfo createFileInfo(MetadataScaleFile metadataScaleFile) throws Exception {
      CommonsMultipartFile commonsMultipartFile = metadataScaleFile.getOriginalFile();
      FileInfo fileInfo = new FileInfo();
      fileInfo.setOriginalfileName(commonsMultipartFile.getOriginalFilename());
      fileInfo.setMimetypes(commonsMultipartFile.getContentType());
      String originalName = commonsMultipartFile.getOriginalFilename();
      String extension = originalName.substring(originalName.indexOf("."));
      fileInfo.setExtension(extension);
      return fileInfo;
   }
   
   public FileInfo writeFile(CommonsMultipartFile commonsMultipartFile, String uploadDir, String folderPath) throws Exception{
      MetadataScaleFile metadataScaleMediumFile = this.createMedium(commonsMultipartFile);
      MetadataScaleFile metadataScaleSmallFile = this.createSmall(metadataScaleMediumFile.getInputStream(),commonsMultipartFile.getContentType(),commonsMultipartFile);
      FileInfo fileInfo = new FileInfo();
      fileInfo.setOriginalfileName(commonsMultipartFile.getOriginalFilename());
      fileInfo.setMimetypes(commonsMultipartFile.getContentType());
      String originalName = commonsMultipartFile.getOriginalFilename();
      String extension = originalName.substring(originalName.indexOf("."));
      fileInfo.setExtension(extension);
      String fileDetail = metadataScaleMediumFile.getWidth() + ";" + metadataScaleMediumFile.getHeight() + ";" + metadataScaleMediumFile.getSize();
      fileDetail = fileDetail + "|" + metadataScaleSmallFile.getWidth() + ";" + metadataScaleSmallFile.getHeight() + ";" + metadataScaleSmallFile.getSize();
      fileInfo.setFileDetail(fileDetail);
      String fileName = UID + getUniqueId();
      fileInfo.setName(fileName);
      fileInfo.setAbsolutePath(folderPath);

      String fileMediumPath = uploadDir + folderPath + "/" + fileName + "_medium";
      FileOutputStream fout = null;
      try {
          File file = new File(fileMediumPath);
          fout = new FileOutputStream(file);
          fout.write(metadataScaleMediumFile.getBytes());
      } finally {
          if (fout != null) {
              fout.close();
          }
      }

      String fileSmallPath = uploadDir + folderPath + "/" + fileName + "_small";
      try {
          File file = new File(fileSmallPath);
          fout = new FileOutputStream(file);
          fout.write(metadataScaleSmallFile.getBytes());
      } finally {
          if (fout != null) {
              fout.close();
          }
      }
      return fileInfo;
   }
   
   public static long getSmallLength(FileInfo fileInfo){
      String fileDetail = fileInfo.getFileDetail();
      String[] fileInfos = fileDetail.split("\\|")[1].split(";");
      long length = Long.parseLong(fileInfos[2]);
      return length;
   }
   
   public static long getMediumLength(FileInfo fileInfo){
      String fileDetail = fileInfo.getFileDetail();
      String[] fileInfos = fileDetail.split("\\|")[0].split(";");
      long length = Long.parseLong(fileInfos[2]);
      return length;
   }
   
   public synchronized String createContainer(String path){
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(new Date(System.currentTimeMillis()));
      String year = ""+ calendar.get(Calendar.YEAR);
      String month = ""+ (calendar.get(Calendar.MONTH) + 1);
      String date = ""+ calendar.get(Calendar.DATE);
      String abstractFolder = "/" + year + "/" + month + "/" + date;
      String folderPath = path + abstractFolder;
      File folder = new File(folderPath);
      if (!folder.isDirectory())
         folder.mkdirs();
      return abstractFolder;
   }

   private static String getUniqueId(){
      final int limit = 100000000;
      int current;
      synchronized (FileInfoUtil.class) {
          current = counter++;
      }
      String id = Integer.toString(current);

      // If you manage to get more than 100 million of ids, you'll
      // start getting ids longer than 8 characters.
      if (current < limit) {
          id = ("00000000" + id).substring(id.length());
      }
      return id;
   }

   public static ImageItem convertImageItem(CommonsMultipartFile commonsMultipartFile){
      String originalName = commonsMultipartFile.getOriginalFilename();
      ImageItem imageItem = new ImageItem();
      imageItem.setFileName(originalName);
      imageItem.setBytes(commonsMultipartFile.getBytes());
      imageItem.setFileType(commonsMultipartFile.getContentType());
      imageItem.setTitle(originalName);
      return imageItem;
   }

   static {
       scaleImageService = new ScaleImageService();
   }
}
